package com.xbongbong.workflow.service.operator.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.workflow.WorkflowDataPojo;
import com.xbongbong.paas.pojo.workflow.WorkflowExplainPojo;
import com.xbongbong.paas.pojo.workflow.WorkflowSubDataPoJo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.WorkflowExplainUtil;
import com.xbongbong.paas.util.WorkflowUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.WorkflowValueTypeEnum;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.pojo.WorkflowOperationsPojo;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.InsertRecordNode;
import com.xbongbong.workflow.service.operator.WorkflowOperatorMainAndSubFormService;
import com.xbongbong.workflow.service.operator.WorkflowOperatorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 此方法主要是用来解决子表单字段赋值给主字段
 * @author 吴峰
 * @date 2021/06/24 9:45
 */
@Service("workflowOperatorMainSubFormServiceImpl")
public class WorkflowOperatorMainSubFormServiceImpl implements WorkflowOperatorMainAndSubFormService<Map<String, JSONArray>> {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowOperatorMainSubFormServiceImpl.class);

    @Resource
    private Map<Integer, WorkflowOperatorService>  workflowOperatorMap;


    @Override
    public Map<String, JSONArray> getInsertFieldListByDataNode(WorkflowOperationsPojo workflowOperationsPojo, WorkflowExplainPojo workflowExplainPojo,
                                                               FieldAttrEntity targetField, Map<Long, PaasFormDataEntityExt> formDataMap, Map<Long, JSONObject> dataMap,
                                                               InsertRecordNode insertRecordNode, WorkflowNodeEntity workflowNodeEntity, WorkflowDataPojo workflowDataPojo, WorkflowTransferPOJO workflowTransferPojo) throws XbbException {
        try {
            String subKey = "";
            String thisAttr = workflowOperationsPojo.getValueAttr();
            Map<Long, Map<String, Map<String, FieldAttrEntity>>> subExplainMap = workflowExplainPojo.getSubExplainMap();

            Map<Long, Map<String, Map<String, FieldAttrEntity>>> workOrderSubExplainMap = workflowExplainPojo.getWorkOrderSubExplainMap();
            // 解开子表单字段如：subForm_1.text_1，将其解开为两个字段subForm_1和text_1，拿到各自的属性，方便后面使用
            if (Objects.equals(WorkflowValueTypeEnum.DYNAMIC_VALUE.getType(), workflowOperationsPojo.getValueType()) && thisAttr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                List<String> thisAttrList = ExplainUtil.getAttrByPoint(workflowOperationsPojo.getValueAttr());
                thisAttr = thisAttrList.get(0);
                subKey = thisAttrList.get(1);
            }
            String targetAttr = workflowOperationsPojo.getAttr();
            // 根据上述解开的字段，获取字段解释，可能为null，只有动态值才有字段，公式和固定值是无固定的字段的
            FieldAttrEntity fieldAttrEntity = WorkflowExplainUtil.getThisSubField( workOrderSubExplainMap, subExplainMap, workflowOperationsPojo.getFormId(),
                    workflowOperationsPojo.getBusinessType(), workflowOperationsPojo.getValueType(),thisAttr, subKey);
            // 拿到子表单数据，子表单数据具有多行的特性
            WorkflowSubDataPoJo workflowSubDataPoJo = WorkflowUtil.getSubData(workflowOperationsPojo, workflowTransferPojo.getData().getNodeId(), formDataMap);
            JSONArray subDataArray = workflowSubDataPoJo.getSubData();
            Map<String, JSONArray> subResultMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(subDataArray)) {
                JSONArray subResultList = new JSONArray();

                for (int i = 0; i < subDataArray.size(); i++) {
                    JSONObject resultJson = new JSONObject();
                    dataMap.put(workflowSubDataPoJo.getNodeId(), subDataArray.getJSONObject(i));
                    WorkflowOperatorService workflowOperatorService = workflowOperatorMap.get(workflowOperationsPojo.getValueType());
                    Object value = workflowOperatorService.operatorByInsertNodeSourceData(workflowNodeEntity, fieldAttrEntity, targetField, formDataMap,
                            dataMap, workflowOperationsPojo, workflowDataPojo, workflowTransferPojo, workflowExplainPojo);
                    resultJson.put(targetAttr, value);
                    subResultList.add(resultJson);
                }
                subResultMap.put(targetAttr, subResultList);
            }
            return subResultMap;
        }  catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowOperatorMainSubFormServiceImpl.getInsertFieldListByDataNode", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public Object getUpdateData(WorkflowOperationsPojo workflowOperationsPojo, WorkflowExplainPojo workflowExplainPojo, FieldAttrEntity targetField,
                                Map<Long, PaasFormDataEntityExt> formDataMap, Map<Long, JSONObject> dataMap, WorkflowNodeEntity workflowNodeEntity,
                                WorkflowDataPojo workflowDataPojo, WorkflowTransferPOJO workflowTransferPojo) throws XbbException {
        try {
            String thisAttr = workflowOperationsPojo.getValueAttr();
            String subKey = "";
            if (Objects.equals(WorkflowValueTypeEnum.DYNAMIC_VALUE.getType(), workflowOperationsPojo.getValueType()) && thisAttr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                List<String> thisAttrList = ExplainUtil.getAttrByPoint(thisAttr);
                thisAttr = thisAttrList.get(0);
                subKey = thisAttrList.get(1);
            }
            FieldAttrEntity fieldAttrEntity = WorkflowExplainUtil.getThisSubField( workflowExplainPojo.getWorkOrderSubExplainMap(), workflowExplainPojo.getSubExplainMap(),
                    workflowOperationsPojo.getFormId(), workflowOperationsPojo.getBusinessType(), workflowOperationsPojo.getValueType(),thisAttr, subKey);
            WorkflowOperatorService workflowOperatorService = workflowOperatorMap.get(workflowOperationsPojo.getValueType());
            return workflowOperatorService.operatorByUpdateNode(workflowNodeEntity, fieldAttrEntity, targetField, formDataMap, dataMap, workflowOperationsPojo, workflowDataPojo, workflowTransferPojo, workflowExplainPojo);

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowOperatorMainSubFormServiceImpl.getUpdateData", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
